#pragma once
#include "types.h"
#include "fs.h"

typedef u32       fd_t;
typedef u32       off_t;
typedef size_t    pid_t;

// system calls
void shutdown(u16 code) __attribute__((noreturn));
ssize_t fork();
ssize_t getpid();
void exit(int status) __attribute__((noreturn));
ssize_t wait(int* status);
int kill(pid_t pid);
int exec(const char* path, char* argv[]);
int getcwd(char* buf, size_t size);

bool access(char* path);
ssize_t open(const char* path, u32 flag);
int close(fd_t fd);
int fstat(fd_t fd, struct stat* stat);
ssize_t read(fd_t fd, char* buf, size_t size);
ssize_t write(fd_t fd, const char* buf, size_t size);
off_t lseek(fd_t fd, off_t offset, whence_t whence);
ssize_t dup(fd_t fd);
int pipe(fd_t fds[2]);

int mknod(const char* path, u16 major, u16 minor);
int link(const char* file, const char* link);
int unlink(const char* path);
int symlink(char* file, char* link);
int mkdir(const char* path);
int chdir(const char* path);

int pause(size_t nticks);
size_t uptime();
char* sbrk(intptr_t increment);
int trace(size_t mask);

int send(u16 sport, u32 dst, u16 dport, char* buf, size_t size);
int recv(u16 dport, u32* src, u16* sport, char* buf, size_t size);
int bind(u16 port);
int unbind(u16 port);

// ulib.c
int stat(const char*, struct stat*);
char* strcpy(char*, const char*);
char* strchr(const char*, char c);
int strcmp(const char*, const char*);
char* gets(char*, int max);
int atoi(const char*);
char* sbrkalloc(int);

// umalloc.c
void* malloc(uint);
void free(void*);

// compiler rt
uint strlen(const char*);
void* memset(void*, int, uint);
void *memmove(void*, const void*, int);
int memcmp(const void *, const void *, uint);
void *memcpy(void *, const void *, uint);

// exec.zig
int execl(const char* path, const char* arg, ...);
int execlp(const char* file, const char* arg, ...);
int execvp(const char* file, char* argv[]);

// printf.zig
void fprintf(int, const char*, ...) __attribute__ ((format (printf, 2, 3)));
void printf(const char*, ...) __attribute__ ((format (printf, 1, 2)));
